package callback

import (
	"encoding/json"
	"errors"
	"fmt"
	"gitee.com/injoyai/goutil/net/conn"
	"gitee.com/injoyai/goutil/net/tcp"
	"time"
)

// Server 服务由一个tcp服务,加协程控制组成
//设置超时时间为3分钟,客户端想要保持长连接,需要设置心跳
type Server struct {
	ser   *tcp.Server
	Limit chan byte
}

// Debug 调试模式会打印底层通讯数据
func (this *Server) Debug(b ...bool) *Server {
	this.ser.Debug(b...)
	return this
}

// Run 执行
func (this *Server) Run() error {
	return this.ser.Run()
}

// NewServer 新建callback服务
// @port,端口
// @fn,数据处理,全部数据走该方法过
// @limit,协程释放数量
func NewServer(port int, fn func(*Msg), limit ...uint) *Server {
	l := make(chan byte, func() uint {
		if len(limit) > 0 && limit[0] > 0 {
			return limit[0]
		}
		return 10
	}())
	s := tcp.NewServer(port)
	s.SetTimeout(time.Minute * 3)
	s.SetDealFunc(func(m *conn.Msg) {
		msg := new(Msg)
		if err := json.Unmarshal(m.Bytes(), msg); err != nil {
			msg.SetErr(err)
			m.Conn().SendBytes(msg.Bytes())
		} else {
			l <- 0
			go func() {
				defer func() {
					if e := recover(); e != nil {
						msg.SetErr(errors.New(fmt.Sprint(e)))
					}
					<-l
				}()
				fn(msg)
				m.Conn().SendBytes(msg.Bytes())
			}()
		}
	})
	return &Server{ser: s, Limit: l}
}
